import si from 'systeminformation';
import { log } from '../utils/logger.js';
import { sshService } from './sshService.js';

/**
 * 服务器监控服务
 */
export class MonitorService {
  /**
   * 获取远程服务器的监控数据
   */
  async getServerMonitoring(connectionId) {
    try {
      // 使用简单的命令组合获取监控数据
      const commands = [
        // CPU使用率
        "top -bn1 | grep 'Cpu(s)' | awk '{print 100 - $8}'",
        // CPU核心数
        "nproc || grep -c ^processor /proc/cpuinfo",
        // 内存信息（总量MB）
        "free -m | awk 'NR==2{print $2}'",
        // 内存使用（已用MB）
        "free -m | awk 'NR==2{print $3}'",
        // 内存使用率
        "free | awk 'NR==2{printf \"%.2f\", $3*100/$2}'",
        // 磁盘使用率
        "df -h / | awk 'NR==2{print $5}'",
        // 运行时间
        "uptime -p 2>/dev/null || uptime | awk -F'up ' '{print $2}' | awk -F',' '{print $1}'",
      ];

      // 并发执行所有命令
      const results = await Promise.all(
        commands.map(cmd => sshService.executeCommand(connectionId, cmd))
      );

      // 检查是否有命令执行失败
      const hasError = results.some(r => r.code !== 0);
      if (hasError) {
        throw new Error('部分监控命令执行失败');
      }

      // 提取结果
      const [cpuUsage, cpuCores, memTotal, memUsed, memUsage, diskUsage, uptime] = results.map(
        r => r.stdout.trim()
      );

      // 格式化运行时间
      const formattedUptime = this.formatUptime(uptime);

      const monitorData = {
        cpu: parseFloat(cpuUsage) || 0,
        memory: parseFloat(memUsage) || 0,
        disk: diskUsage || '0%',
        uptime: formattedUptime
      };

      log.debug('获取服务器监控数据成功', { connectionId, data: monitorData });
      
      return monitorData;
    } catch (error) {
      log.error('获取服务器监控数据失败', { 
        error: error.message, 
        connectionId 
      });
      throw error;
    }
  }

  /**
   * 格式化运行时间
   * 将 "up 1 week, 1 day, 9 hours, 5 minutes" 格式化为 "8天 9小时 5分钟"
   */
  formatUptime(uptimeStr) {
    try {
      if (!uptimeStr || uptimeStr === 'unknown') {
        return '未知';
      }

      // 移除 "up " 前缀
      let str = uptimeStr.replace(/^up\s+/, '').trim();
      
      let days = 0;
      let hours = 0;
      let minutes = 0;

      // 提取周数
      const weekMatch = str.match(/(\d+)\s+week/);
      if (weekMatch) {
        days += parseInt(weekMatch[1]) * 7;
        str = str.replace(/\d+\s+weeks?,?\s*/, '');
      }

      // 提取天数
      const dayMatch = str.match(/(\d+)\s+day/);
      if (dayMatch) {
        days += parseInt(dayMatch[1]);
        str = str.replace(/\d+\s+days?,?\s*/, '');
      }

      // 提取小时
      const hourMatch = str.match(/(\d+)\s+hour/);
      if (hourMatch) {
        hours = parseInt(hourMatch[1]);
        str = str.replace(/\d+\s+hours?,?\s*/, '');
      }

      // 提取分钟
      const minMatch = str.match(/(\d+)\s+min/);
      if (minMatch) {
        minutes = parseInt(minMatch[1]);
      }

      // 如果格式不匹配，尝试其他格式
      if (days === 0 && hours === 0 && minutes === 0) {
        // 尝试匹配类似 "1:23" 格式（小时:分钟）
        const timeMatch = uptimeStr.match(/(\d+):(\d+)/);
        if (timeMatch) {
          hours = parseInt(timeMatch[1]);
          minutes = parseInt(timeMatch[2]);
        }
      }

      // 构建中文格式
      const parts = [];
      if (days > 0) parts.push(`${days}天`);
      if (hours > 0) parts.push(`${hours}小时`);
      if (minutes > 0) parts.push(`${minutes}分钟`);

      return parts.length > 0 ? parts.join(' ') : '刚启动';
    } catch (error) {
      log.error('格式化运行时间失败', { error: error.message, uptimeStr });
      return uptimeStr;
    }
  }

  /**
   * 获取本地服务器监控数据（监控后端服务器自身）
   */
  async getLocalMonitoring() {
    try {
      const [cpu, mem, disk, networkStats, load, osInfo, processes] = await Promise.all([
        si.currentLoad(),
        si.mem(),
        si.fsSize(),
        si.networkStats(),
        si.currentLoad(),
        si.osInfo(),
        si.processes()
      ]);

      const monitoring = {
        cpu: {
          usage: Math.round(cpu.currentLoad * 100) / 100,
          cores: cpu.cpus.length
        },
        memory: {
          total: Math.round(mem.total / 1024 / 1024),
          used: Math.round(mem.used / 1024 / 1024),
          free: Math.round(mem.free / 1024 / 1024),
          usage: Math.round((mem.used / mem.total) * 100 * 100) / 100,
          swap_total: Math.round(mem.swaptotal / 1024 / 1024),
          swap_used: Math.round(mem.swapused / 1024 / 1024),
          swap_free: Math.round(mem.swapfree / 1024 / 1024)
        },
        disk: disk.map(d => ({
          filesystem: d.fs,
          size: d.size,
          used: d.used,
          available: d.available,
          usage: Math.round(d.use * 100) / 100 + '%',
          mount: d.mount
        })),
        network: {
          rx_bytes: networkStats[0]?.rx_bytes || 0,
          tx_bytes: networkStats[0]?.tx_bytes || 0,
          rx_sec: networkStats[0]?.rx_sec || 0,
          tx_sec: networkStats[0]?.tx_sec || 0
        },
        load: {
          load1: load.avgLoad,
          load5: 0,
          load15: 0
        },
        system: {
          uptime: osInfo.uptime,
          os: `${osInfo.distro} ${osInfo.release}`,
          processes: processes.all
        }
      };

      return monitoring;
    } catch (error) {
      log.error('获取本地监控数据失败', { error: error.message });
      throw error;
    }
  }

  /**
   * 获取简化的监控数据（用于侧边栏显示）
   */
  async getSimpleMonitoring(connectionId) {
    try {
      return await this.getServerMonitoring(connectionId);
    } catch (error) {
      log.error('获取简化监控数据失败', { error: error.message, connectionId });
      return {
        cpu: 0,
        memory: 0,
        disk: '0%',
        uptime: 'unknown'
      };
    }
  }
}

// 创建单例
export const monitorService = new MonitorService();

